package com.basic.library.view.hover;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import androidx.recyclerview.R;
import com.basic.library.utils.NoDoubleClickListener;
import com.chad.library.adapter.base.BaseQuickAdapter;

/**
 * @author yj
 * @description 悬停 只支持线性布局
 * https://github.com/374901588/RVSuspensionBarTest
 */
public class SectionRecycleView extends RecyclerView {

    private int mCurrentPosition; //group的位置
    private View mSuspensionBar;
    private SuspensionCallback mSuspensionCallback;

    public SectionRecycleView(@NonNull Context context) {
        this(context, null);
    }

    public SectionRecycleView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.recyclerViewStyle);
    }

    public SectionRecycleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        addListener();
    }

    void addListener() {
        addOnScrollListener(new OnScrollListener() {
            LinearLayoutManager linearLayoutManager;
            int mSuspensionHeight;
            boolean isdown;

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                try {
                    switch (newState) {
                        case SCROLL_STATE_IDLE: //停止滚动
                            final BaseQuickAdapter adapter = (BaseQuickAdapter) getAdapter();
                            if (linearLayoutManager == null) {
                                linearLayoutManager = (LinearLayoutManager) getLayoutManager();
                            }
                            int firstVisPos = linearLayoutManager.findFirstVisibleItemPosition();
                            for (int i = firstVisPos; i >= 0; i--) {
                                SuspensionBean bean = (SuspensionBean) adapter.getData().get(i);
                                if (bean.isHeader()) {
                                    mCurrentPosition = i;
                                    break;
                                }
                            }
                            updateSuspensionBar(mCurrentPosition);
                            if (isdown && firstVisPos == 0)
                                mSuspensionBar.setY(0);
                            break;
                        case SCROLL_STATE_DRAGGING: //正在被外部拖拽,一般为用户正在用手指滚动

                            break;
                        case SCROLL_STATE_SETTLING: //自动滚动开始

                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                try {
                    super.onScrolled(recyclerView, dx, dy);
                    final BaseQuickAdapter adapter = (BaseQuickAdapter) getAdapter();
                    // mSuspensionBar.getHeight()的高度的获取如果是在 onCreate() 或者是
                    // 在 RecyclerView.OnScrollListener 被初始化的时候去获取，获得的结果
                    // 会为 0，因此此时 mSuspensionBar 还没有初始化完成
                    if (mSuspensionHeight == 0)
                        mSuspensionHeight = mSuspensionBar.getHeight();
                    if (linearLayoutManager == null) {
                        linearLayoutManager = (LinearLayoutManager) getLayoutManager();
                    }

                    int firstVisPos = linearLayoutManager.findFirstVisibleItemPosition();

                    SuspensionBean firstVisibleItem = (SuspensionBean) adapter.getData().get(firstVisPos);
                    if (firstVisPos + 1 > adapter.getData().size() - 1) {
                        for (int i = firstVisPos; i >= 0; i--) {
                            SuspensionBean bean = (SuspensionBean) adapter.getData().get(i);
                            if (bean.isHeader()) {
                                mCurrentPosition = i;
                                break;
                            }
                        }
                        updateSuspensionBar(mCurrentPosition);
                        mSuspensionBar.setY(0);
                        return;
                    }
                    SuspensionBean nextItem = (SuspensionBean) adapter.getData().get(firstVisPos + 1);
                    View nextView = linearLayoutManager.findViewByPosition(firstVisPos + 1);

                    //如果是网格布局，就在firstVisPos + 1 至 firstVisPos + span位置里找是否有下一排的第一个
                    if (linearLayoutManager instanceof GridLayoutManager) {
                        GridLayoutManager g = (GridLayoutManager) linearLayoutManager;
                        int span = g.getSpanCount();
                        for (int i = firstVisPos + 1; i <= firstVisPos + span; i++) {
                            if (i < adapter.getData().size() - 1) {
                                SuspensionBean bean = (SuspensionBean) adapter.getData().get(i);
                                if (g.getSpanSizeLookup().getSpanIndex(i, span) == 0) {
                                    nextItem = bean;
                                    nextView = linearLayoutManager.findViewByPosition(i);
                                    break;
                                }
                            }
                        }
                    }

                    if (nextView == null) return;
                    isdown = dy <= 0;
                    //上滑情况下
                    if (dy > 0) {
                        //只有第一个可见的 Item 的下一个 Item 的类型
                        //为 Post类型时才需要动态设置效果
                        if (nextItem.isHeader()) {

                            if (nextView.getTop() <= mSuspensionHeight) {
                                //被顶掉的效果
                                mSuspensionBar.setY(-(mSuspensionHeight - nextView.getTop()));
                            } else {
                                //否则就直接回到 Y = 0 的位置
                                mSuspensionBar.setY(0);
                            }
                        }

                        //判断是否需要更新悬浮条
                        if (mCurrentPosition != firstVisPos && firstVisibleItem.isHeader()) {
                            mCurrentPosition = firstVisPos;
                            //根据 mCurrentPosition 的值，更新 mSuspensionBar
                            updateSuspensionBar(mCurrentPosition);
                            mSuspensionBar.setY(0);
                        }
                    } else { //下滑情况
                        // 1、nextItem -> Post and firstVisibleItem -> Comment       mCurrentPosition = ((Comment) firstVisibleItem).getParentPostPosition()
                        // 2、nextItem -> Post and firstVisibleItem -> Post          mCurrentPosition = firstVisPos
                        // 3、nextItem -> Comment and firstVisibleItem -> Comment    mSuspensionBar 不动
                        // 4、nextItem -> Comment and firstVisibleItem -> Post       mSuspensionBar 不动
                        if (nextItem.isHeader()) {
                            if (firstVisibleItem.isHeader())
                                mCurrentPosition = firstVisPos;
                            else {
                                for (int i = firstVisPos; i >= 0; i--) {
                                    SuspensionBean bean = (SuspensionBean) adapter.getData().get(i);
                                    if (bean.isHeader()) {
                                        mCurrentPosition = i;
                                        break;
                                    }
                                }
                            }
                            updateSuspensionBar(mCurrentPosition);

                            if (nextView.getTop() <= mSuspensionHeight) {
                                //被顶掉的效果
                                mSuspensionBar.setY(-(mSuspensionHeight - nextView.getTop()));
                            } else {
                                mSuspensionBar.setY(0);
                            }
                        } else {
                            //列表自动定位时，如scrollToPosition
                            if (firstVisPos == 0) {
                                if (firstVisibleItem.isHeader())
                                    mCurrentPosition = firstVisPos;
                                updateSuspensionBar(mCurrentPosition);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void updateSuspensionBar(int mCurrentPosition) {
        if (mSuspensionCallback != null) {
            if (mSuspensionBar == null)
                throw new NullPointerException("设置悬停视图mSuspensionBar");
            mSuspensionCallback.updateSuspensionBar(mSuspensionBar, mCurrentPosition);
        }
    }

    /**
     * 设置悬停view
     *
     * @param mSuspensionBar
     */
    public void setmSuspensionBar(View mSuspensionBar) {
        this.mSuspensionBar = mSuspensionBar;
        mSuspensionBar.setOnClickListener(new NoDoubleClickListener() {
            @Override
            protected void onNoDoubleClick(View v) {
                if (mSuspensionCallback != null) {
                    mSuspensionCallback.onBarClick(mCurrentPosition);
                }
            }
        });
    }

    public void addSuspensionCallback(SuspensionCallback mSuspensionCallback) {
        this.mSuspensionCallback = mSuspensionCallback;
    }

    /**
     * i 悬停视图在列表中的位置
     */
    public interface SuspensionCallback {
        void updateSuspensionBar(View v, int i);

        void onBarClick(int i);
    }

    public interface SuspensionBean {
        public boolean isHeader();
    }
}
